<template>
  <el-card shadow="hover" class="box-card">
    <template #header>
      <div class="card-header">
        <el-form :inline="true">
          <el-form-item label="表达式">
            <el-input class="expression" v-model="cronValue" readonly placeholder="表达式" clearable />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onConfirm">确定</el-button>
            <el-button @click="onClose">关闭</el-button>
          </el-form-item>
        </el-form>
      </div>
    </template>
    <el-tabs type="border-card" v-model="activeName">
      <el-tab-pane name="second" label="秒">
        <el-radio-group v-model="secondType">
          <el-radio value="all" label="all" size="small">每秒 允许的通配符[, - * /]</el-radio>
          <el-radio value="range" label="range" size="small">周期从
            <el-input-number v-model="second.range.start" :min="1" :max="58" size="small" controls-position="right"/>-
            <el-input-number v-model="second.range.end" :min="2" :max="59" size="small" controls-position="right"/>秒
          </el-radio>
          <el-radio value="cycle" label="cycle" size="small">从
            <el-input-number v-model="second.cycle.start" :min="0" :max="59" size="small" controls-position="right"/>秒开始,每 
            <el-input-number v-model="second.cycle.step" :min="1" :max="59" size="small" controls-position="right"/>秒执行一次
          </el-radio>
          <el-radio value="appoint" label="appoint" size="small">指定
            <el-checkbox-group v-model="second.appoint">
              <template v-for="item in secondList" :key="item">
                <br v-if="item % 10 === 0" />
                <el-checkbox :label="item" :value="item">{{ item }}</el-checkbox>
              </template>
            </el-checkbox-group>
          </el-radio>
        </el-radio-group>
      </el-tab-pane>
      <el-tab-pane name="minute" label="分">
        <el-radio-group v-model="minuteType">
          <el-radio value="all" label="all" size="small">分钟 允许的通配符[, - * /]</el-radio>
          <el-radio value="range" label="range" size="small">周期从
            <el-input-number v-model="minute.range.start" :min="1" :max="58" size="small" controls-position="right"/>-
            <el-input-number v-model="minute.range.end" :min="2" :max="59" size="small" controls-position="right"/>分钟
          </el-radio>
          <el-radio value="cycle" label="cycle" size="small">从
            <el-input-number v-model="minute.cycle.start" :min="0" :max="59" size="small" controls-position="right"/>分钟开始,每 
            <el-input-number v-model="minute.cycle.step" :min="1" :max="59" size="small" controls-position="right"/>分钟执行一次
          </el-radio>
          <el-radio value="appoint" label="appoint" size="small">指定
            <el-checkbox-group v-model="minute.appoint">
              <template v-for="item in minuteList" :key="item">
                <br v-if="item % 10 === 0" />
                <el-checkbox :label="item" :value="item">{{ item }}</el-checkbox>
              </template>
            </el-checkbox-group>
          </el-radio>
        </el-radio-group>
      </el-tab-pane>
      <el-tab-pane name="hour" label="时">
        <el-radio-group v-model="hourType">
          <el-radio value="all" label="all" size="small">小时 允许的通配符[, - * /]</el-radio>
          <el-radio value="range" label="range" size="small">周期从
            <el-input-number v-model="hour.range.start" :min="0" :max="23" size="small" controls-position="right"/>-
            <el-input-number v-model="hour.range.end" :min="0" :max="23" size="small" controls-position="right"/>小时
          </el-radio>
          <el-radio value="cycle" label="cycle" size="small">从
            <el-input-number v-model="hour.cycle.start" :min="0" :max="23" size="small" controls-position="right"/>小时开始,每 
            <el-input-number v-model="hour.cycle.step" :min="0" :max="23" size="small" controls-position="right"/>小时执行一次
          </el-radio>
          <el-radio value="appoint" label="appoint" size="small">指定
            <el-checkbox-group v-model="hour.appoint">
              <template v-for="item in hourList" :key="item">
                <br v-if="item % 6 === 0" />
                <el-checkbox :label="item" :value="item">{{ item }}</el-checkbox>
              </template>
            </el-checkbox-group>
          </el-radio>
        </el-radio-group>
      </el-tab-pane>
      <el-tab-pane name="day" label="日">
        <el-radio-group v-model="dayType">
          <el-radio value="all" label="all" size="small">日 允许的通配符[, - * / L W]</el-radio>
          <el-radio value="range" label="range" size="small">周期从
            <el-input-number v-model="day.range.start" :min="1" :max="31" size="small" controls-position="right"/>-
            <el-input-number v-model="day.range.end" :min="1" :max="31" size="small" controls-position="right"/>日
          </el-radio>
          <el-radio value="cycle" label="cycle" size="small">从
            <el-input-number v-model="day.cycle.start" :min="1" :max="31" size="small" controls-position="right"/>日开始,每 
            <el-input-number v-model="day.cycle.step" :min="1" :max="31" size="small" controls-position="right"/>日执行一次
          </el-radio>
          <el-radio value="work_day" label="work_day" size="small">每月
            <el-input-number v-model="day.work_day.start" :min="1" :max="31" size="small" controls-position="right"/>号最近的那个工作日
          </el-radio>
          <el-radio value="last_day" label="last_day" size="small">本月最后一天</el-radio>
          <el-radio value="no_appoint" label="no_appoint" size="small">不指定</el-radio>
          <el-radio value="appoint" label="appoint" size="small">指定
            <el-checkbox-group v-model="day.appoint">
              <template v-for="(item, index) in dayList" :key="item">
                <br v-if="index == 11 || index == 21" />
                <el-checkbox :label="item" :value="item">{{ item }}</el-checkbox>
              </template>
            </el-checkbox-group>
          </el-radio>
        </el-radio-group>
      </el-tab-pane>
      <el-tab-pane name="month" label="月">
        <el-radio-group v-model="monthType">
          <el-radio value="all" label="all" size="small">月 允许的通配符[, - * /]</el-radio>
          <el-radio value="range" label="range" size="small">周期从
            <el-input-number v-model="month.range.start" :min="1" :max="12" size="small" controls-position="right"/>-
            <el-input-number v-model="month.range.end" :min="2" :max="12" size="small" controls-position="right"/>月
          </el-radio>
          <el-radio value="cycle" label="cycle" size="small">从
            <el-input-number v-model="month.cycle.start" :min="1" :max="12" size="small" controls-position="right"/>月开始,每 
            <el-input-number v-model="month.cycle.step" :min="1" :max="12" size="small" controls-position="right"/>月执行一次
          </el-radio>
          <el-radio value="no_appoint" label="no_appoint" size="small">不指定</el-radio>
          <el-radio value="appoint" label="appoint" size="small">指定
            <el-checkbox-group v-model="month.appoint">
              <template v-for="item in monthList" :key="item">
                <br v-if="item % 7 === 0" />
                <el-checkbox :label="item" :value="item">{{ item }}</el-checkbox>
              </template>
            </el-checkbox-group>
          </el-radio>
        </el-radio-group>
      </el-tab-pane>
      <el-tab-pane name="week" label="周">
        <el-radio-group v-model="weekType">
          <el-radio value="all" label="all" size="small">周 允许的通配符[, - * / L #]</el-radio>
          <el-radio value="cycle" label="cycle" size="small">周期从
            <el-input-number v-model="week.cycle.start" :min="1" :max="7" size="small" controls-position="right"/>-
            <el-input-number v-model="week.cycle.step" :min="2" :max="7" size="small" controls-position="right"/>
          </el-radio>
          <el-radio value="cycle_range" label="cycle_range" size="small">第
            <el-input-number v-model="week.cycle_range.start" :min="1" :max="4" size="small" controls-position="right"/>周的星期
            <el-input-number v-model="week.cycle_range.end" :min="1" :max="7" size="small" controls-position="right"/>
          </el-radio>
          <el-radio value="last_week" label="last_week" size="small">本月最后一个星期
            <el-input-number v-model="week.last_week.start" :min="1" :max="7" size="small" controls-position="right"/>
          </el-radio>
          <el-radio value="no_appoint" label="no_appoint" size="small">不指定</el-radio>
          <el-radio value="appoint" label="appoint" size="small">指定
            <el-checkbox-group v-model="week.appoint">
              <template v-for="item in weekList" :key="item">
                <el-checkbox :label="item" :value="item">{{ item }}</el-checkbox>
              </template>
            </el-checkbox-group>
          </el-radio>
        </el-radio-group>
      </el-tab-pane>
      <el-tab-pane name="year" label="年">
        <el-radio-group v-model="yearType">
          <el-radio value="all" label="all" size="small">每年</el-radio>
          <el-radio value="no_appoint" label="no_appoint" size="small">不指定 允许的通配符[, - * /] 非必填</el-radio>
          <el-radio value="range" label="range" size="small">周期从
            <el-input-number v-model="year.range.start" :min="2013" :max="2099" size="small" controls-position="right"/>-
            <el-input-number v-model="year.range.end" :min="2013" :max="2099" size="small" controls-position="right"/>
          </el-radio>
        </el-radio-group>
      </el-tab-pane>
    </el-tabs>
  </el-card>
</template>
<script setup>
defineOptions({ name: 'Cron' })
const props = defineProps({
  modelValue : { type: String, default: () => '', required: true},
})
const $emit = defineEmits(['update:modelValue', 'close'])

const onConfirm  = () => {
  $emit("update:modelValue", cronValue.value);
  onClose();
}

const onClose  = () => {
  $emit("close");
}

const activeName = ref('second')

const secondList = ref(Array.from({ length: 60 }, (_, i) => (i < 10 ? (i+'').padStart(2, '0') : i)))
const secondType = ref('all')
const second = ref({
  all: '*',
  range: {
    start: 1,
    end: 2,
  },
  cycle: {
    start: 1,
    step: 1
  },
  appoint: []
})

const minuteList = ref(Array.from({ length: 60 }, (_, i) => (i < 10 ? (i+'').padStart(2, '0') : i)))
const minuteType = ref('all')
const minute = ref({
  all: '*',
  range: {
    start: 1,
    end: 2,
  },
  cycle: {
    start: 1,
    step: 1
  },
  appoint: []
})

const hourList = ref(Array.from({ length: 24 }, (_, i) => (i < 10 ? (i+'').padStart(2, '0') : i)))
const hourType = ref('all')
const hour = ref({
  all: '*',
  range: {
    start: 1,
    end: 2,
  },
  cycle: {
    start: 1,
    step: 1
  },
  appoint: []
})

const dayList = ref(Array.from({ length: 31 }, (_, i) => i+1))
const dayType = ref('all')
const day = ref({
  all: '*',
  range: {
    start: 1,
    end: 2,
  },
  cycle: {
    start: 1,
    step: 1
  },
  work_day: {
    start: 1,
    end: 'W'
  },
  last_day: 'L',
  no_appoint: '?',
  appoint: [],
})

const monthList = ref(Array.from({ length: 12 }, (_, i) => i+1))
const monthType = ref('all')
const month = ref({
  all: '*',
  range: {
    start: 1,
    end: 2,
  },
  cycle: {
    start: 1,
    step: 1
  },
  no_appoint: '?',
  appoint: [],
})

const weekList = ref(Array.from({ length: 7 }, (_, i) => i+1))
const weekType = ref('all')
const week = ref({
  all: '*',
  cycle_range: {
    start: 1,
    end: 2,
  },
  cycle: {
    start: 1,
    step: 1
  },
  last_week: {
    start: 1,
    end: 'L'
  },
  no_appoint: '?',
  appoint: [],
})

const yearType = ref('all')
const year = ref({
  all: '*',
  no_appoint: '',
  range: {
    start: 2024,
    end: 2025,
  },
})

const getValue = (obj, key) => {
  let _value = '';
  const _type = Object.prototype.toString.call(obj[key]);
  if (_type == '[object String]') {
    _value = obj[key]
  } else if(_type == '[object Array]') {
    _value = obj[key].length ? obj[key].map(v=>parseInt(v)).join(',') : '?'
  } else if(_type == '[object Object]') {
    if(key == 'cycle') {
      _value = obj[key].start + '/' + obj[key].step
    } else if(key == 'range') {
      _value = obj[key].start + '-' + obj[key].end
    } else if(key == 'cycle_range') {
      _value = obj[key].start + '#' + obj[key].end
    } else if(key == 'work_day' || key == 'last_week') {
      _value = obj[key].start + obj[key].end
    }
  }
  return _value
}

const cronValue = computed(() => {
  let _second = getValue(second.value, secondType.value)
  let _minute = getValue(minute.value, minuteType.value)
  let _hour = getValue(hour.value, hourType.value)
  let _day = getValue(day.value, dayType.value)
  let _month = getValue(month.value, monthType.value)
  let _week = getValue(week.value, weekType.value)
  let _year = getValue(year.value, yearType.value)
  return `${_second} ${_minute} ${_hour} ${_day} ${_month} ${_week} ${_year}`
})

</script>
<style scoped>
.el-card {
  width: 800px;
}
.el-tabs {
  height: 450px;
}
.el-tabs :deep(.el-tabs__content){
  height: 100%;
}
.el-radio-group {
  width: 100%;
  align-items: flex-start;
  flex-direction: column;
}
.el-radio {
  margin: 10px;
  align-items: flex-start;
}
.expression {
  width: 450px
}
</style>